#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <sys/wait.h>
#include <sys/types.h>
#include <assert.h>
#include <unistd.h>
using namespace std;
int main()
{
    //  1.创建管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);// pipefd[0]:读 pipefd[1]:写
    assert(n != 1); // 只在degug模式里是有效的
    (void)n; // 如果没有这句代码那n就是只被定义没有被使用，在release下编译就会产生大量告警情况，为了防止告警，就加上这句代码
#ifdef DEBUG // 条件编译 gcc 里加 -DDEBUG 才会执行此代码
    cout << "pipefd[0]:" << pipefd[0] << endl;
    cout << "pipefd[1]:" << pipefd[1] << endl;
#endif
    
    // 2.创建子进程
    pid_t id = fork();
    assert(id != -1);
    if(id == 0)
    {
    // 子进程 - 读
    // 3.构建单向通信管道，父进程写入，子进程读取
    // 3.1 关闭子进程不需要的fd
        close(pipefd[1]);
        char buffer[1024];
        while(true)
        {
            ssize_t s =  read(pipefd[0],buffer,sizeof(buffer)-1);
            if(s > 0)
            {
                // buffer[s]
                cout << "i am a child,pid:" << getpid() << "读到的数据:" << buffer << endl;
            }
        }
        // close(pipefd[0]);
        exit(0);
    }
    // 父进程 - 写
    // 3.构建单向通信管道，父进程写入，子进程读取
    // 3.1 关闭父进程不需要的fd
    close(pipefd[0]);
    string message = "我是父进程，我给子进程发消息";
    int count = 0;
    char send_buffer[1024];
    while(true)
    {
        // 3.2 构建一个变化的字符串
       snprintf(send_buffer,sizeof(send_buffer),"%s[%d] : %d",message.c_str(),getpid(),count++);
        // 3.3 写入
       write(pipefd[1],send_buffer,strlen(send_buffer));
        // 3.4 故意sleep
       sleep(1);
    }
    close(pipefd[1]);
    pid_t ret = waitpid(id,nullptr,0);
    assert(ret > 0);
    (void)ret;
    return 0;
}





